package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.controller.base.BaseLibraryController;
import com.zenithmind.library.pojo.dto.BookCreateDTO;
import com.zenithmind.library.pojo.dto.BookUpdateDTO;
import com.zenithmind.library.pojo.query.BookQuery;
import com.zenithmind.library.pojo.vo.BookDetailVO;
import com.zenithmind.library.pojo.vo.BookVO;
import com.zenithmind.library.service.BookQueryService;
import com.zenithmind.library.service.BookManagementService;
import com.zenithmind.library.service.BookInventoryService;
import com.zenithmind.library.service.BookStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 图书管理控制器
 * 遵循单一职责原则：只负责HTTP请求处理，不包含业务逻辑
 * 遵循依赖倒置原则：依赖抽象接口而不是具体实现
 *
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/v1/books")
@RequiredArgsConstructor
@Tag(name = "图书管理", description = "图书信息的增删改查操作")
public class BookController extends BaseLibraryController {

    // 依赖抽象接口，遵循依赖倒置原则
    private final BookQueryService bookQueryService;
    private final BookManagementService bookManagementService;
    private final BookInventoryService bookInventoryService;
    private final BookStatisticsService bookStatisticsService;

    @GetMapping
    @Operation(summary = "分页查询图书", description = "根据条件分页查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBookPage(@Valid BookQuery query) {
        logOperation("分页查询图书", query);
        try {
            PageResult<BookVO> result = bookQueryService.getBookPage(query);
            logOperationSuccess("分页查询图书", result);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "分页查询图书");
        }
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询图书详情", description = "根据ID查询图书详细信息")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<BookDetailVO> getBookDetail(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("查询图书详情", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            BookDetailVO result = bookQueryService.getBookDetail(id);
            if (result == null) {
                return buildNotFoundResult("图书不存在");
            }
            logOperationSuccess("查询图书详情", result);
            return buildSuccessResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "查询图书详情");
        }
    }

    @PostMapping
    @Operation(summary = "创建图书", description = "新增图书信息")
    @PreAuthorize("hasAuthority('library:book:create')")
    public Result<BookVO> createBook(@Valid @RequestBody BookCreateDTO createDTO, BindingResult bindingResult) {
        logOperation("创建图书", createDTO);

        // 验证参数
        Result<Void> validation = handleValidationErrors(bindingResult);
        if (!validation.isSuccess()) {
            return buildParamErrorResult("参数验证失败");
        }

        try {
            Result<BookVO> result = bookManagementService.createBook(createDTO);
            if (result.isSuccess()) {
                logOperationSuccess("创建图书", result.getData());
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "创建图书");
        }
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新图书", description = "更新图书信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<BookVO> updateBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Valid @RequestBody BookUpdateDTO updateDTO, BindingResult bindingResult) {
        logOperation("更新图书", id, updateDTO);

        // 验证参数
        Result<Void> idValidation = validateId(id, "图书ID");
        if (!idValidation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        Result<Void> validation = handleValidationErrors(bindingResult);
        if (!validation.isSuccess()) {
            return buildParamErrorResult("参数验证失败");
        }

        try {
            Result<BookVO> result = bookManagementService.updateBook(id, updateDTO);
            if (result.isSuccess()) {
                logOperationSuccess("更新图书", result.getData());
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "更新图书");
        }
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除图书", description = "根据ID删除图书")
    @PreAuthorize("hasAuthority('library:book:delete')")
    public Result<Void> deleteBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("删除图书", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookManagementService.deleteBook(id);
            if (result.isSuccess()) {
                logOperationSuccess("删除图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "删除图书");
        }
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除图书", description = "根据ID列表批量删除图书")
    @PreAuthorize("hasAuthority('library:book:delete')")
    public Result<Void> batchDeleteBooks(@RequestBody List<String> ids) {
        logOperation("批量删除图书", ids);

        // 验证参数
        Result<Void> validation = validateIds(ids, "图书ID列表");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID列表不能为空");
        }

        try {
            Result<Void> result = bookManagementService.batchDeleteBooks(ids);
            if (result.isSuccess()) {
                logOperationSuccess("批量删除图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "批量删除图书");
        }
    }

    @PutMapping("/{id}/publish")
    @Operation(summary = "上架图书", description = "将图书设置为上架状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> publishBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("上架图书", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookManagementService.publishBook(id);
            if (result.isSuccess()) {
                logOperationSuccess("上架图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "上架图书");
        }
    }

    @PutMapping("/{id}/unpublish")
    @Operation(summary = "下架图书", description = "将图书设置为下架状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> unpublishBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("下架图书", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookManagementService.unpublishBook(id);
            if (result.isSuccess()) {
                logOperationSuccess("下架图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "下架图书");
        }
    }

    @PutMapping("/{id}/recommend")
    @Operation(summary = "推荐图书", description = "将图书设置为推荐状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> recommendBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("推荐图书", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookManagementService.recommendBook(id);
            if (result.isSuccess()) {
                logOperationSuccess("推荐图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "推荐图书");
        }
    }

    @PutMapping("/{id}/unrecommend")
    @Operation(summary = "取消推荐图书", description = "取消图书的推荐状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> unrecommendBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        logOperation("取消推荐图书", id);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookManagementService.unrecommendBook(id);
            if (result.isSuccess()) {
                logOperationSuccess("取消推荐图书", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "取消推荐图书");
        }
    }

    @GetMapping("/isbn/{isbn}")
    @Operation(summary = "根据ISBN查询图书", description = "根据ISBN查询图书信息")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<BookVO> getBookByIsbn(
            @Parameter(description = "ISBN", required = true) @PathVariable String isbn) {
        logOperation("根据ISBN查询图书", isbn);
        try {
            BookVO result = bookQueryService.getBookByIsbn(isbn);
            if (result == null) {
                return buildNotFoundResult("图书不存在");
            }
            return buildSuccessResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "根据ISBN查询图书");
        }
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "根据分类查询图书", description = "根据分类ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByCategory(
            @Parameter(description = "分类ID", required = true) @PathVariable String categoryId,
            @Valid BookQuery query) {
        logOperation("根据分类查询图书", categoryId, query);

        // 验证参数
        Result<Void> validation = validateId(categoryId, "分类ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("分类ID不能为空");
        }

        try {
            PageResult<BookVO> result = bookQueryService.getBooksByCategory(categoryId, query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "根据分类查询图书");
        }
    }

    @GetMapping("/author/{authorId}")
    @Operation(summary = "根据作者查询图书", description = "根据作者ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String authorId,
            @Valid BookQuery query) {
        logOperation("根据作者查询图书", authorId, query);

        // 验证参数
        Result<Void> validation = validateId(authorId, "作者ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("作者ID不能为空");
        }

        try {
            PageResult<BookVO> result = bookQueryService.getBooksByAuthor(authorId, query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "根据作者查询图书");
        }
    }

    @GetMapping("/publisher/{publisherId}")
    @Operation(summary = "根据出版社查询图书", description = "根据出版社ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByPublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String publisherId,
            @Valid BookQuery query) {
        logOperation("根据出版社查询图书", publisherId, query);

        // 验证参数
        Result<Void> validation = validateId(publisherId, "出版社ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("出版社ID不能为空");
        }

        try {
            PageResult<BookVO> result = bookQueryService.getBooksByPublisher(publisherId, query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "根据出版社查询图书");
        }
    }

    @GetMapping("/search")
    @Operation(summary = "搜索图书", description = "根据关键词搜索图书")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> searchBooks(
            @Parameter(description = "搜索关键词", required = true) @RequestParam String keyword,
            @Valid BookQuery query) {
        logOperation("搜索图书", keyword, query);
        try {
            PageResult<BookVO> result = bookQueryService.searchBooks(keyword, query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "搜索图书");
        }
    }

    @GetMapping("/recommended")
    @Operation(summary = "获取推荐图书", description = "获取推荐图书列表")
    public Result<PageResult<BookVO>> getRecommendedBooks(@Valid BookQuery query) {
        logOperation("获取推荐图书", query);
        try {
            PageResult<BookVO> result = bookQueryService.getRecommendedBooks(query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "获取推荐图书");
        }
    }

    @GetMapping("/new")
    @Operation(summary = "获取新书", description = "获取新书列表")
    public Result<PageResult<BookVO>> getNewBooks(@Valid BookQuery query) {
        logOperation("获取新书", query);
        try {
            PageResult<BookVO> result = bookQueryService.getNewBooks(query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "获取新书");
        }
    }

    @GetMapping("/popular")
    @Operation(summary = "获取热门图书", description = "获取热门图书列表")
    public Result<PageResult<BookVO>> getPopularBooks(@Valid BookQuery query) {
        logOperation("获取热门图书", query);
        try {
            PageResult<BookVO> result = bookQueryService.getPopularBooks(query);
            return buildPageResult(result);
        } catch (Exception e) {
            return handleBusinessException(e, "获取热门图书");
        }
    }

    @PutMapping("/{id}/stock")
    @Operation(summary = "更新图书库存", description = "更新图书的库存信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> updateBookStock(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Parameter(description = "总库存数量", required = true) @RequestParam Integer totalCopies,
            @Parameter(description = "可借阅数量", required = true) @RequestParam Integer availableCopies) {
        logOperation("更新图书库存", id, totalCopies, availableCopies);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookInventoryService.updateBookStock(id, totalCopies, availableCopies);
            if (result.isSuccess()) {
                logOperationSuccess("更新图书库存", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "更新图书库存");
        }
    }

    @PutMapping("/{id}/rating")
    @Operation(summary = "更新图书评分", description = "更新图书的评分信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> updateBookRating(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Parameter(description = "评分", required = true) @RequestParam Double rating) {
        logOperation("更新图书评分", id, rating);

        // 验证参数
        Result<Void> validation = validateId(id, "图书ID");
        if (!validation.isSuccess()) {
            return buildParamErrorResult("图书ID不能为空");
        }

        try {
            Result<Void> result = bookStatisticsService.updateBookRating(id, rating);
            if (result.isSuccess()) {
                logOperationSuccess("更新图书评分", "成功");
            }
            return result;
        } catch (Exception e) {
            return handleBusinessException(e, "更新图书评分");
        }
    }

    // 注意：导入导出功能应该移到专门的管理控制器中，这里暂时保留但使用BookService的原有方法
    @PostMapping("/import")
    @Operation(summary = "导入图书数据", description = "批量导入图书数据")
    @PreAuthorize("hasAuthority('library:book:import')")
    public Result<String> importBooks(@RequestBody List<BookCreateDTO> books) {
        logOperation("导入图书数据", books.size());

        // 验证参数
        if (books == null || books.isEmpty()) {
            return buildParamErrorResult("导入数据不能为空");
        }

        try {
            // 这里需要通过BookService的原有方法，因为我们还没有创建专门的导入导出服务
            // 在实际项目中，应该创建BookImportExportService
            return Result.fail("导入功能暂未实现，请使用BookService的原有方法");
        } catch (Exception e) {
            return handleBusinessException(e, "导入图书数据");
        }
    }

    @GetMapping("/export")
    @Operation(summary = "导出图书数据", description = "导出图书数据到Excel文件")
    @PreAuthorize("hasAuthority('library:book:export')")
    public Result<String> exportBooks(@Valid BookQuery query) {
        logOperation("导出图书数据", query);
        try {
            // 这里需要通过BookService的原有方法，因为我们还没有创建专门的导入导出服务
            // 在实际项目中，应该创建BookImportExportService
            return Result.fail("导出功能暂未实现，请使用BookService的原有方法");
        } catch (Exception e) {
            return handleBusinessException(e, "导出图书数据");
        }
    }
}
